package com.letv.ads;

import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageInfo;
import android.graphics.Rect;
import android.text.TextUtils;
import android.webkit.WebSettings;
import android.webkit.WebView;

import com.letv.adlib.managers.status.ad.AdStatusManager;
import com.letv.adlib.managers.status.ad.IAdDownloadInformer;
import com.letv.adlib.managers.status.video.IVideoStatusInformer;
import com.letv.adlib.model.ad.common.AdInfoWrapper;
import com.letv.adlib.model.services.CommonAdDataService;
import com.letv.adlib.sdk.types.AdElement;
import com.letv.adlib.sdk.types.AdElementMime;
import com.letv.adlib.sdk.types.AdElementSplash;
import com.letv.ads.db.AdsDBHandler;
import com.letv.ads.http.AdsHttpApi;
import com.letv.ads.http.LetvSimpleAsyncTask;
import com.letv.ads.util.ApkDownloadAsyncTask;
import com.letv.ads.util.Commons;
import com.letv.ads.util.DataUtils;
import com.letv.ads.util.IAdJSBridge;
import com.letv.ads.util.IOfflineCachedAdCallback;
import com.letv.ads.util.LogInfo;
import com.letv.ads.util.SearchKeyWordCallBack;
import com.letv.component.player.utils.NativeInfos;
import com.letv.core.download.image.ImageDownloader;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 静态图片广告管理类
 */
public class AdsManager {
    private static final String TAG = "AdsManager";
    private boolean isShowAd = true;
    private boolean isShowOfflineAd = true;

    private static AdsManager instance;

    private Context context;

    /**
     * 是否是联通流量订购用户
     */
    private boolean isWoOrderUser = false;

    public int cpuSupportLevel = 0;

    /**
     * JS桥接接口
     */
    public IAdJSBridge iAdJSBridge;

    public boolean supportM3U8() {
        return cpuSupportLevel > 0;
    }

    /**
     * 开机引导图广告
     */
    private AdElementMime beginAdInfo;

    /**
     * 焦点图第三张
     */
    private ArrayList<AdElementMime> focusAdInfo;

    /**
     * 搜索全屏广告
     */
    // private AdElementMime fullbackAdInfo;

    private VipCallBack vipCallBack;

    private VideoCallBack videoCallBack;
    /**
     * 是否是推送播放
     */
    private boolean isFromPush = false;
    /**
     * 是否是二维码扫描
     */
    private boolean isFromQRCode = false;
    /**
     * 二维码视频扫描视频播放时间
     */
    private long isQRCodeVideoTime = 0;
    /**
     * 二维码地址
     */
    private String letvQRCodeUrl = null;

    public boolean hasInited = false;

    private AdsManager() {

    }

    public synchronized static AdsManager getInstance() {
        if (instance == null) {
            instance = new AdsManager();
        }

        return instance;
    }

    private IVideoStatusInformer informer;

    /**
     * 初始化广告所需数据
     *
     * @param context
     *            Application context
     * @param version
     *            版本号
     * @param pcode
     *            PCODE
     * @param kv
     * @param test
     *            是否测试接口
     */
    public void initAdData(Context context, String kv, String platform,
            String version, String pcode, boolean test) {
        if (hasInited)
            return;
        this.context = context;
        Commons.VERSION = version;
        Commons.PCODE = pcode;
        Commons.KV = kv;
        Commons.PLATFORM = platform;
        Commons.MAC = DataUtils.getMacAddress(context);
        Commons.DEVICE = DataUtils.getDeviceName();
        Commons.DEVICE_INFO = DataUtils.getSystemName() + "_"
                + DataUtils.getBrandName() + "_" + Commons.DEVICE;
        Commons.DEVICE_ID = DataUtils.generateDeviceId(context);
        Commons.PVERSION = DataUtils.getPVersion(Commons.VERSION);
        Commons.TEST = test;

        SharedPreferences preferences = context.getSharedPreferences(
                "ad_srtting", Context.MODE_PRIVATE);
        isShowAd = preferences.getBoolean("isShow", false);
        isShowOfflineAd = preferences.getBoolean("isShowOfflineAd", false);
    }

    /**
     * 得到上一次的开机图
     */
    public AdElementMime getBeginAdInfo() {
        if (beginAdInfo != null) {
            return beginAdInfo;
        }

        ArrayList<AdElementSplash> ads = AdsDBHandler.getAd(context, "begin");

        if (ads != null && ads.size() > 0) {
            beginAdInfo = ads.get(0);
        }

        updateBeginAdInfo();

        return beginAdInfo;
    }

    public AdElementSplash getBeginVideoAd() {
        AdElementMime adElementMime = getBeginAdInfo();
        if (adElementMime == null)
            return null;
        if (((AdElementSplash) adElementMime).needDownload == 1) {
            String localPath = CommonAdDataService.getBootVideoLocalPath(
                    adElementMime, context);
            if (!TextUtils.isEmpty(localPath) && new File(localPath).exists()) {
                ((AdElementSplash) adElementMime).localPath = localPath;
                return (AdElementSplash) adElementMime;
            }
        }
        return null;
    }

    /**
     * 得到离线缓存视频前帖广告
     *
     * @param context
     *            上下文
     * @param cid
     *            频道id
     * @param aid
     *            专辑id
     * @param vid
     *            视频id
     * @param mmsid
     *            媒资id
     * @param uid
     *            当前登录用户id
     * @param vlen
     *            时长
     * @param downloadInformer
     *            广告下载状态通知 不要可以传null
     * @param videoStatusCallback
     *            正片视频下载状态通知 不给 可以传null
     */
    public void getOfflineCachedVideoAd(Context context, int cid, long aid,
            long vid, String mmsid, String uid, String vlen,
            boolean isSupportM3U8, boolean isVipVideo, boolean disableAvd,
            boolean isWoOrderUser, IAdDownloadInformer downloadInformer,
            IOfflineCachedAdCallback videoStatusCallback) {

        new RequestOfflineAdTask(context, cid, aid, vid, mmsid, uid, vlen,
                isSupportM3U8, isVipVideo, disableAvd, isWoOrderUser,
                downloadInformer, videoStatusCallback).start();
    }

    /**
     * 是否含有开机广告
     *
     * @return
     */
    public boolean hasBeginAdInfo() {
        if (beginAdInfo != null) {
            return true;
        }

        ArrayList<AdElementSplash> ads = AdsDBHandler.getAd(context, "begin");

        if (ads != null && ads.size() > 0) {
            beginAdInfo = ads.get(0);
        }
        return beginAdInfo == null ? false : true;
    }

    /**
     * 上报付费影片广告？
     *
     * @param mContext
     * @param cid
     * @param aid
     * @param vid
     * @param mmsid
     * @param uuid
     * @param uid
     * @param vlen
     * @param py
     * @param ty
     * @param isVipVideo
     * @param disableAvd
     */
    public void getFrontVipAd(Context mContext, int cid, long aid, long vid,
            String mmsid, String uuid, String uid, String vlen, String py,
            String ty, boolean isVipVideo, boolean disableAvd,
            String cuePointType) {
        AdsHttpApi.getFrontVipAd(mContext, cid + "", aid + "", vid + "", mmsid,
                uuid, uid, vlen, py, ty, null, true, isVipVideo, disableAvd,
                cuePointType);
    }

    /**
     * 开机广告更新
     */
    public void updateBeginAdInfo() {
        Thread thread = new Thread() {
            @Override
            public void run() {
                checkData(AdsHttpApi.getBeginImgAd(context), "begin");
            }
        };
        thread.start();
    }

    /**
     * 得到焦点图广告
     * 
     * @return 广告队列
     */
    public ArrayList<AdElementMime> getFocusAdInfo() {
        return AdsHttpApi.getFocusImgAd(context);
    }

    /**
     * 得到半屏底部广告，
     * */
    public ArrayList<AdElementMime> getBottomAdData(int cid, long aid,
            long vid, String mmsid) {
        return AdsHttpApi.getBottomAdData(context, cid, aid, vid, mmsid);
    }

    /**
     * 得到顶部通栏广告
     */
    public AdElementMime getBannerAdInfo(String cid, String pid) {
        AdElementMime bannerAdInfo = checkData(
                AdsHttpApi.getTopBannerAd(context, cid, pid), "banner");
        return bannerAdInfo;
    }

    private void cacheWebpage(String url) {
        WebView webView = new WebView(context);
        WebSettings webSettings = webView.getSettings();
        webSettings.setAppCacheEnabled(true);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webView.loadUrl(url);
    }

    /**
     * 检查结果数据是否正常
     */
    private AdElementMime checkData(ArrayList<AdElementMime> ads, String ad) {
        if ("begin".equals(ad) && AdsDBHandler.has(context, ad)) {
            AdsDBHandler.remove(context, ad);
        }
        LogInfo.log("bootPic", "checkData....");
        if (ads != null && ads.size() > 0) {
            AdElementMime adItem = ads.get(0);
            if ("begin".equals(ad)) {
                AdsDBHandler.saveAd(context, ad, adItem);
                ArrayList<AdElementSplash> adElementSplashs = AdsDBHandler
                        .getAd(context, "begin");
                if (adElementSplashs != null && adElementSplashs.size() > 0) {
                    beginAdInfo = adElementSplashs.get(0);
                }
            }
            for (AdElementMime mAdElementMime : ads) {
                try {
                    LogInfo.log("bootPic", "ads mediaFileUrl ="
                            + mAdElementMime.mediaFileUrl + "  type="
                            + mAdElementMime.mediaFileType);
                    switch (mAdElementMime.mediaFileType) {
                    case AdElement.AdMediaType.HTML: {
                        cacheWebpage(mAdElementMime.mediaFileUrl);
                        break;
                    }
                    case AdElement.AdMediaType.BITMAP: {
                        ImageDownloader.getInstance(context).download(mAdElementMime.mediaFileUrl);
                        break;
                    }
                    case AdElement.AdMediaType.VIDEO: {
                        if (mAdElementMime instanceof AdElementSplash) {
                            new CommonAdDataService().downloadAdVideoMaterial(
                                    context, mAdElementMime);
                        }
                        break;
                    }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    continue;
                }
            }
            return adItem;
        }
        LogInfo.log("bootPic", "adsList is null...");
        return null;
    }

    /**
     * 是否显示广告，用初始化接口设置
     */
    public boolean isShowAd() {
        return isShowAd;
    }

    /**
     * 是否显示离线广告，用初始化接口设置
     */
    public boolean isShowOfflineAd() {
        return isShowOfflineAd;
    }

    /**
     * 初始化是否显示广告
     */
    public void setShowAd(boolean isShowAd) {
        SharedPreferences preferences = context.getSharedPreferences(
                "ad_srtting", Context.MODE_PRIVATE);
        Editor editor = preferences.edit();
        editor.putBoolean("isShow", isShowAd);
        editor.commit();
        this.isShowAd = isShowAd;
    }

    /**
     * 初始化是否显示离线广告
     */
    public void setShowOfflineAd(boolean isShowOfflineAd) {
        SharedPreferences preferences = context.getSharedPreferences(
                "ad_srtting", Context.MODE_PRIVATE);
        Editor editor = preferences.edit();
        editor.putBoolean("isShowOfflineAd", isShowOfflineAd);
        editor.commit();
        this.isShowOfflineAd = isShowOfflineAd;
    }

    public VipCallBack getVipCallBack() {
        return vipCallBack;
    }

    public void setVipCallBack(VipCallBack vipCallBack) {
        this.vipCallBack = vipCallBack;
    }

    public VideoCallBack getVideoCallBack() {
        return videoCallBack;
    }

    public void setVideoCallBack(VideoCallBack videoCallBack) {
        this.videoCallBack = videoCallBack;
    }

    public boolean isVip() {
        if (vipCallBack != null) {
            return vipCallBack.isVip();
        }

        return false;
    }

    public interface VipCallBack {

        boolean isVip();
    }

    public interface VideoCallBack {
        /**
         * 执行暂停正片动作
         */
        void pauseVideo();

        /**
         * 执行继续播放正片动作
         */
        void resumeVideo();

        /**
         * 获取播放器显示区域
         *
         * @return
         */
        Rect getPlayerRect();
    }

    /**
     * @deprecated use initAd(Context context, boolean useTestServer, boolean
     *             showLog, int supportLevel, String deviceId, IAdJSBridge
     *             iAdJSBridge) insteadof
     */
    public void initAd(Context context, boolean useTestServer, boolean showLog,
            int supportLevel, String deviceId) {
        initAd(context, useTestServer, showLog, supportLevel, deviceId, null);
    }

    /**
     * 初始化广告配置信息 ， 需要在开机读到接口时调用
     *
     * @param context
     * @param useTestServer
     *            是否开始测试模式，默认为线上模式
     * @param showLog
     *            是否开启LOG，默认不开启
     * @param supportLevel
     *            CPU支持的播放级别
     * @param deviceId
     *            设备id
     * @param iAdJSBridge
     *            webview JS 桥接
     */
    public void initAd(Context context, boolean useTestServer, boolean showLog,
            int supportLevel, String deviceId, IAdJSBridge iAdJSBridge) {
        if (hadInited(context))
            return;
        this.iAdJSBridge = iAdJSBridge;
        try {
            if (!TextUtils.isEmpty(deviceId)) {
                Commons.DEVICE_ID = deviceId;
            }
            if (TextUtils.isEmpty(Commons.PVERSION)
                    || TextUtils.isEmpty(Commons.DEVICE_ID)) {
                String pv = "";
                try {
                    PackageInfo packInfo = context.getPackageManager()
                            .getPackageInfo(context.getPackageName(), 0);
                    pv = packInfo.versionName;
                } catch (Exception e) {
                }
                this.initAdData(context, "androidPhone", "android", pv,
                        Commons.PCODE, useTestServer);
            }

            if (supportLevel == 0) {
                int sLevel = NativeInfos.getSupportLevel();
                if (sLevel == NativeInfos.SUPPORT_MP4_LEVEL
                        || !NativeInfos.ifSupportVfpOrNeon()) {
                    sLevel = NativeInfos.SUPPORT_MP4_LEVEL;
                }
                supportLevel = sLevel;
            }

            this.cpuSupportLevel = supportLevel;

            CommonAdDataService.initAd(context, useTestServer, showLog,
                    supportLevel, Commons.DEVICE_ID, Commons.P1, Commons.P2,
                    Commons.P3, Commons.PVERSION, Commons.PCODE);
        } catch (IllegalArgumentException iae) {
            iae.printStackTrace();
        }
    }

    private boolean hadInited(Context context) {
        if (hasInited)
            return true;
        hasInited = true;

        try {
            ActivityManager mActivityManager = (ActivityManager) context
                    .getSystemService(Service.ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> mRunningProcess = mActivityManager
                    .getRunningAppProcesses();
            for (ActivityManager.RunningAppProcessInfo amProcess : mRunningProcess) {
                if (android.os.Process.myPid() == amProcess.pid) {
                    // LogInfo.log("ads","amProcess.processName＝"+amProcess.processName);
                    return amProcess.processName.contains(":");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 传入广告配置信息
     *
     * @param config
     */
    public void initRemoteConfig(String config) {
        CommonAdDataService.initRemoteConfig(config);
    }

    /**
     * 请求搜索框广告
     */
    private ArrayList<AdElementMime> getSearchKeyWord(Context context) {
        return AdsHttpApi.getSearchKeyWord(context);
    }

    /**
     * 搜索框广告成功 曝光
     *
     * @param mAdElementMime
     */
    private void searchKeyWordExposure(AdElementMime mAdElementMime,
            boolean destoryImmediately) {
        if (mAdElementMime != null) {
            LogInfo.log("ads", "post id=" + mAdElementMime.adTag);
            AdStatusManager manager = new AdStatusManager(mAdElementMime);
            manager.onAdPlayStart();
            // if (destoryImmediately) {
            // 曝光后直接销毁对象
            manager.onAdPlayComplete();
            // }
        }
    }

    /**
     * 请求点播暂停
     */
    private class RequestSearchKeyWord extends
            LetvSimpleAsyncTask<List<AdElementMime>> {
        Context context;
        SearchKeyWordCallBack mCallBack;

        public RequestSearchKeyWord(Context context,
                SearchKeyWordCallBack mCallBack) {
            super(context);
            this.context = context;
            this.mCallBack = mCallBack;
            LogInfo.log("ads", "banner keywords : RequestSearchKeyWord-+");

        }

        @Override
        public List<AdElementMime> doInBackground() {
            if (isCancel()) {
                return null;
            }
            ArrayList<AdElementMime> searchKeyWord = getSearchKeyWord(context);
            if (searchKeyWord != null && searchKeyWord.size() > 0) {
                LogInfo.log("ads",
                        "banner keywords : doInBackground-,searchKeyWord"
                                + searchKeyWord);
                return searchKeyWord;
            }
            LogInfo.log("ads", "banner keywords : doInBackground-+");
            return null;
        }

        @Override
        public void onPostExecute(List<AdElementMime> result) {
//            LogInfo.log("ads", "banner keywords : onPostExecute-"+result+",mCallBack"+mCallBack);
            if (result != null && mCallBack != null) {
                for (AdElementMime elementMime : result) {
                    LogInfo.log("ads","return text is "+elementMime.text+",commtype="+elementMime.commonType);
                    if (elementMime != null && !TextUtils.isEmpty(elementMime.text)) {
                        // 通栏的关键词是1
                        if (elementMime.commonType == 1) {
                            LogInfo.log("ads", "banner keywords :" + elementMime.text);
                            mCallBack.updateSearchBannerTextView(elementMime);
                            searchKeyWordExposure(elementMime, false);
                        } else if (elementMime.commonType == 0) {
                            LogInfo.log("ads", "search box keywords :" + elementMime.text);
                            // 原来的关键词
                            mCallBack.updateSearchTextView(elementMime.text);
                            searchKeyWordExposure(elementMime, true);
                        }
                    }
                }
            }
        }

        @Override
        public void onPreExecute() {

        }
    }

    private RequestSearchKeyWord mRequestSearchKeyWord;

    public void requestSearchKeyWord(Context context, SearchKeyWordCallBack mSearchKeyWordCallBack) {
        LogInfo.log("ads","begin request keyword ");
        cancellSearchKeyWord();
        mRequestSearchKeyWord = new RequestSearchKeyWord(context, mSearchKeyWordCallBack);
        mRequestSearchKeyWord.start();

    }

    public void cancellSearchKeyWord() {
        if (mRequestSearchKeyWord != null) {
            mRequestSearchKeyWord.cancel(true);
        }
        mRequestSearchKeyWord = null;
    }

    /**
     * 给广告发送反馈日志，
     *
     * @param uniqueId 传入手机号
     */
    public void sendFeedbackToAd(String uniqueId) {
        AdsHttpApi.sendFeedbackToAd(uniqueId);
    }
    //======================================================================================

    public boolean isFromPush() {
        return isFromPush;
    }

    public void setFromPush(boolean isFromPush) {
        this.isFromPush = isFromPush;
        LogInfo.log("ads","---=-=====set isFromPush ="+isFromPush);
    }

    public boolean isFromQRCode() {
        return isFromQRCode;
    }

    public void setFromQRCode(boolean isFromQRCode) {
        this.isFromQRCode = isFromQRCode;
    }

    public long getIsQRCodeVideoTime() {
        return isQRCodeVideoTime;
    }

    public void setIsQRCodeVideoTime(long isQRCodeVideoTime) {
        this.isQRCodeVideoTime = isQRCodeVideoTime;
    }

    public String getLetvQRCodeUrl() {
        return letvQRCodeUrl;
    }

    public void setLetvQRCodeUrl(String letvQRCodeUrl) {
        this.letvQRCodeUrl = letvQRCodeUrl;
    }

    /*
     * 下载并安装APK
     */
    public void downloadAndInstallApk(String url, String appName) {
        if (context != null)
            ApkDownloadAsyncTask.downloadApk(context, url, appName);
    }

    /*
     * 第一次安装
     */
    public void installFirst() {
        if (context != null)
            CommonAdDataService.appIsFirstInstalled(context);
    }

    /**
     * 清楚所有通知
     */
    public void clearDownloadNotify() {
        ApkDownloadAsyncTask.clearNotifys();
    }

    /**
     * 网络状态通知
     *
     * @param state NETTYPE_NO = 0;
     *              NE
     *              NETTYPE_UNKOWN = -1;TTYPE_WIFI = 1;
     *              NETTYPE_2G = 2;
     *              NETTYPE_3G = 3;
     *              NETTYPE_4G = 4;
     */
    public void notifyNetStatusChange(Context context, int state) {
        LogInfo.log("ads", "cur net status " + state);
        CommonAdDataService.notifyNetStatusChange(context, state);
    }

    class RequestOfflineAdTask extends LetvSimpleAsyncTask<AdInfoWrapper> {

        private Context mContext;

        private String cid;

        private String aid;

        private String vid;

        private String mmsid;

        private String uid;

        private String vlen;

        private boolean isVipVideo;

        private boolean isSupportM3U8;

        private boolean disableAvd;

        private boolean isHotVideo;

        private boolean isOfflineVideo;

        private IAdDownloadInformer downloadInformer;

        private IOfflineCachedAdCallback callback;

        public RequestOfflineAdTask(Context context, int cid, long aid, long vid, String mmsid,
                                    String uid, String vlen, boolean isSupportM3U8, boolean isVipVideo,
                                    boolean disableAvd, boolean isWoOrder, IAdDownloadInformer downInformer, IOfflineCachedAdCallback callback) {
            super(context);
            mContext = context;
            this.cid = String.valueOf(cid);
            this.aid = String.valueOf(aid);
            this.vid = String.valueOf(vid);
            this.mmsid = mmsid;
            this.uid = uid;
            this.vlen = vlen;
            this.disableAvd = disableAvd;
            this.isVipVideo = isVipVideo;
            this.isSupportM3U8 = isSupportM3U8;
            this.downloadInformer = downInformer;
            this.callback = callback;
            isWoOrderUser = isWoOrder;
        }

        @Override
        public void onPreExecute() {

        }

        @Override
        public AdInfoWrapper doInBackground() {
            try {
                if (isCancel()) {
                    LogInfo.log("ads", "getDemandFrontAd=--6");
                    if (callback != null) {
                        callback.onError();
                    }
                    return null;
                }
                LogInfo.log("ads", "----------start----");
                return AdsHttpApi.getOfflineCachedAd(mContext, cid, aid, vid, mmsid, "", uid, vlen, "", "",
                        downloadInformer, true, isVipVideo, disableAvd, isHotVideo, isOfflineVideo);
            } catch (Exception e) {
                if (callback != null) {
                    callback.onError();
                }
                return null;
            }
        }

        @Override
        public void onPostExecute(AdInfoWrapper result) {
            if (callback != null) {
                callback.onSuccess(result);
            }
        }
    }
}
